#include "cvertex.h"

#include <iostream>

CVertex::CVertex()
{
	this->setPosition(0.0, 0.0, 0.0);
	this->clearEdgelist();
	this->clearFaceList();
	this->m_bNormalSet = false;
	this->m_pParentMesh = NULL;
	this->m_OriginalPosition = this->m_Position;
	this->m_AimPosition = this->m_Position;
}

CVertex::CVertex(const CVertex & ori)
{
	this->setPosition(ori.m_Position.m_fX, ori.m_Position.m_fY, ori.m_Position.m_fZ);
	this->m_pParentMesh = ori.m_pParentMesh;
	this->m_bNormalSet = ori.m_bNormalSet;
	this->m_OriginalPosition = ori.m_OriginalPosition;
	this->m_Normal = ori.m_Normal;
	this->m_AimPosition = ori.m_AimPosition;
}

CVertex::CVertex(double fX, double fY, double fZ, CMesh * pParentMesh)
{
	this->setPosition(fX, fY, fZ);
	this->clearEdgelist();
	this->clearFaceList();
	this->m_bNormalSet = false;
	this->m_pParentMesh = pParentMesh;
	this->m_OriginalPosition = this->m_Position;
	this->m_AimPosition = this->m_Position;
}

CVertex::CVertex(CPoint3f P, CMesh * pParentMesh)
{
	this->setPosition(P);
	this->clearEdgelist();
	this->clearFaceList();
	this->m_bNormalSet = false;
	this->m_pParentMesh = pParentMesh;
	this->m_OriginalPosition = this->m_Position;
	this->m_AimPosition = this->m_Position;
}

double CVertex::getX()
{
	return this->m_Position.GetX();
}

double CVertex::getY()
{
	return this->m_Position.GetY();
}

double CVertex::getZ()
{
	return this->m_Position.GetZ();
}

CPoint3f CVertex::getPosition()
{
	return this->m_Position;
}

double CVertex::getOriginalX()
{
	return this->m_OriginalPosition.GetX();
}

double CVertex::getOriginalY()
{
	return this->m_OriginalPosition.GetY();
}

double CVertex::getOriginalZ()
{
	return this->m_OriginalPosition.GetZ();
}

CPoint3f CVertex::getOriginalPosition()
{
	return this->m_OriginalPosition;
}

double CVertex::getAimX()
{
	return this->m_AimPosition.GetX();
}

double CVertex::getAimY()
{
	return this->m_AimPosition.GetY();
}

double CVertex::getAimZ()
{
	return this->m_AimPosition.GetZ();
}

CPoint3f CVertex::getAimPosition()
{
	return this->m_AimPosition;
}

CPoint3f CVertex::getNormal()
{
	return this->m_Normal;
}

bool CVertex::isNormalSet()
{
	return this->m_bNormalSet;
}

CMesh * CVertex::getParentMesh()
{
	return this->m_pParentMesh;
}

void CVertex::setX(double fX)
{
	this->m_Position.SetX(fX);
}

void CVertex::setY(double fY)
{
	this->m_Position.SetY(fY);
}
void CVertex::setZ(double fZ)
{
	this->m_Position.SetZ(fZ);
}

void CVertex::setPosition(double fX, double fY, double fZ)
{
	this->m_Position.Set(fX, fY, fZ);
}

void CVertex::setPosition(CPoint3f point)
{
	this->m_Position.Set(point.GetX(), point.GetY(), point.GetZ());
}

void CVertex::setAimPosition(double fX, double fY, double fZ)
{
	this->m_AimPosition.Set(fX, fY, fZ);
}

void CVertex::setAimPosition(CPoint3f point)
{
	this->m_AimPosition.Set(point.GetX(), point.GetY(), point.GetZ());
}

void CVertex::setNormal(double fX, double fY, double fZ)
{
	this->m_Normal.Set(fX, fY, fZ);
	this->m_bNormalSet = true;
}

void CVertex::setNormal(CPoint3f point)
{
	this->m_Normal.Set(point.GetX(), point.GetY(), point.GetZ());
	this->m_bNormalSet = true;
}

void CVertex::SetParentMesh(CMesh * pParent)
{
	this->m_pParentMesh = pParent;
}

void CVertex::addEdge(CEdge * pEdge)
{
	this->m_EdgeList.push_back(pEdge);
}

void CVertex::addFace(CFace * pFace)
{
	this->m_FaceList.push_back(pFace);
}

void CVertex::removeEdge(CEdge * pEdge)
{
	bool bFound = false;
	for (unsigned i = 0; !bFound && i < this->m_EdgeList.size(); ++i)
	{
		if (pEdge == this->m_EdgeList.at(i))
		{
			this->m_EdgeList.erase(this->m_EdgeList.begin() + i);
			bFound = true;
		}
	}
}

void CVertex::removeFace(CFace * pFace)
{
	bool bFound = false;
	for (int i = 0; !bFound && i < this->m_FaceList.size(); ++i)
	{
		if (pFace == this->m_FaceList.at(i))
		{
			this->m_FaceList.erase(this->m_FaceList.begin() + i);
			bFound = true;
		}
	}
}

void CVertex::computeNormal()
{
	CPoint3f PTemp(0.0, 0.0, 0.0);
	for (int i = 0; i < this->m_FaceList.size(); ++i)
	{
		CFace * pFace = this->m_FaceList.at(i);
		if (!pFace->isNormalSet())
			pFace->computeNormal();
		PTemp.Add(pFace->getNormal());
	}
	PTemp.Div((double)this->m_FaceList.size());
	PTemp.normalize();
	this->setNormal(PTemp);
	this->m_bNormalSet = true;
}

void CVertex::clearEdgelist()
{
	this->m_EdgeList.clear();
}

void CVertex::clearFaceList()
{
	this->m_FaceList.clear();
}
